#include "mainwindow.h"
#include "ui_mainwindow.h"

#include "esp8266.h"
#include "gy39.h"

extern int read_smoke();
extern "C"{
#include "beep_test.h"
#include "led_test.h"
extern int init_step();
extern void set_step(int c);
extern int init_light();
extern void led_onOff(int isOn);
extern int init_fan();
extern void fan_onOff(int isOn);
extern void init_smoke();

}

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);



    connect(ESP8266::get(), &ESP8266::sigData, this, [&](QByteArray data)
    {
        parseAndDisplay(data);
    });
#if 1
    //GY39::get()
    connect(this, &MainWindow::sigLight, this, [&](float l)
    {
        ui->label_L->setText(QString("光照：%1 lux").arg(QString::number(l, 'f', 2)));
        std::string ll = QString::number(l, 'f', 2).toStdString();
        qDebug() <<"****11111111*****" << ll.c_str();
        post(TOPIC_SUN, ll.c_str());
        if(l >= 70)
            led_onOff(0);
        else
            led_onOff(1);
    });
    connect(this, &MainWindow::sigData, this, [&](float t, float h)
    {
        ui->label_T->setText(QString("温度：%1°C").arg(QString::number(t, 'f', 2)));
        ui->label_H->setText(QString("湿度：%1%").arg(QString::number(h, 'f', 2)));

        post(TOPIC_H, std::to_string(h).c_str());
        post(TOPIC_T, std::to_string(t).c_str());
    });
#endif

    connect(GY39::get(), &GY39::sigRecvData, this, [&](QByteArray response)
    {
        std::thread([&, response](){
            buffer.append(response);

        LABEL:
            int index = 0;
            if(buffer.size() >= 9)
            {
                if(buffer.at(0) == 0x5A && buffer.at(1) == 0x5A)
                {
                    index = 2;
                    if(buffer.at(2) == 0x15 && buffer.at(3) == 0x04)
                    {
                        QByteArray frame = buffer.mid(0, 9);
                        // 校验和验证
                        if (verifyChecksum(frame))
                        {
                            // 解析数据
                            quint16 dataFront = (static_cast<quint8>(frame[4]) << 8) | static_cast<quint8>(frame[5]);
                            quint16 dataBack = (static_cast<quint8>(frame[6]) << 8) | static_cast<quint8>(frame[7]);

                            quint32 tmp = (dataFront << 16) | dataBack;
                            static quint32 light = 0;
                            if(light != tmp)
                            {
                                light = tmp;
                                emit sigLight(light / 100.0);
                                qDebug() << "light:" << light;
                            }
                            index = 9;
                        }
                    }
                    else if(buffer.at(2) == 0x45 && buffer.size() >= 12)
                    {
                        if(buffer.at(3) == 0x0A)
                        {
                            index = 12;

                            QByteArray frame = buffer.mid(0, 15);
                            if (verifyChecksum(frame, frame.at(14)))
                            {
                                // 解析温度
                                quint16 temperatureRaw = (static_cast<quint8>(frame[4]) << 8) | static_cast<quint8>(frame[5]);
                                float temperature = static_cast<float>(temperatureRaw) / 100.0;

                                // 解析气压
                                quint32 pressureRaw = (static_cast<quint32>(frame[6]) << 24) |
                                                      (static_cast<quint32>(frame[7]) << 16) |
                                                      (static_cast<quint32>(frame[8]) << 8) |
                                                      static_cast<quint32>(frame[9]);
                                float pressure = static_cast<float>(pressureRaw) / 100.0;

                                // 解析湿度
                                quint16 humidityRaw = (static_cast<quint8>(frame[10]) << 8) | static_cast<quint8>(frame[11]);
                                float humidity = static_cast<float>(humidityRaw) / 100.0;

                                // 解析海拔
                                quint16 altitudeRaw = (static_cast<quint8>(frame[12]) << 8) | static_cast<quint8>(frame[13]);
                                float altitude = static_cast<float>(altitudeRaw) / 1.0;

                                qDebug() << "Temperature:" << temperature << "°C";
                                qDebug() << "Pressure:" << pressure << "hPa";
                                qDebug() << "Humidity:" << humidity << "%";
                                qDebug() << "Altitude:" << altitude << "m";
                                emit sigData(temperature, humidity);
                            }
                            else
                                qDebug() << "verify Checksum fail";
                        }
                    }
                }
            }

            if(index != 9 && index != 12)
            {
                while (buffer.at(index)!=0x5A && index <= buffer.size())
                {
                    index++;
                }
            }
            //qDebug() << "index=" <<index;
            // 移除已经处理过的数据
            buffer = buffer.mid(index);
            if(buffer.size() >= 9)
            {
                goto LABEL;
            }
        }).detach();
    });


    QTimer *timer = new QTimer(this);
    connect(timer, &QTimer::timeout, this, [&]
    {
        int s = read_smoke();
        static int last = 0, count = 0;
        count++;
        if(s!=last || count >= 6)
        {
            count = 0;
            last = s;
            post(TOPIC_S, std::to_string(s).c_str());
        }
        if(s)
        {
            ui->label_S->setText("烟雾：异常");
            beep_onOff(1);
        }
        else
        {
            ui->label_S->setText("烟雾：正常");
            beep_onOff(0);
        }
    });
    timer->start(500);

    init_light();
    init_fan();
    init_step();
    init_beep();

    beep_onOff(0);
    ui->pushButton_led->setVisible(false);
}

MainWindow::~MainWindow()
{
    delete ui;
}

// 发送 POST 指令的函数
void MainWindow::post(const char *topic, const char *msg, const char *uid)
{
    char msgbuf[MAX_MSG_SIZE];
    int len = snprintf(msgbuf, sizeof(msgbuf), "cmd=2&uid=%s&topic=%s&msg=%s\r\n", uid, topic, msg);
    if (len < 0)
    {
        fprintf(stderr, "Error: Message buffer overflow\n");
        return;
    }
    qDebug() << "post:" << msgbuf;
    ESP8266::get()->sendDataToServer(topic, msgbuf);
}

// 解析接收到的数据并显示到对应的 label 上
void MainWindow::parseAndDisplay(const QByteArray& data)
{
    // 假设数据格式为 "cmd=2&uid=xxx&topic=xxx&msg=xxx\r\n"
    QString strData = QString::fromUtf8(data);
    QStringList parts = strData.split("&");

    QString topic;
    QString msg;

    for (const QString& part : parts) {
        QStringList keyValue = part.split("=");
        if (keyValue.size() == 2) {
            if (keyValue[0] == "topic") {
                topic = keyValue[1];
            } else if (keyValue[0] == "msg") {
                msg = keyValue[1].trimmed();
            }
        }
    }

    if (!topic.isEmpty() && !msg.isEmpty())
    {
        qDebug() << "***********2222****************" << topic << msg;
        if (topic == TOPIC_LED) {
            if(msg == "false")
                ui->pushButton_led->setText("开灯");
            else
                ui->pushButton_led->setText("关灯");
        }
        else if (topic == TOPIC_FAN)
        {
            if(msg == "false")
            {
                ui->pushButton_fan->setText("打开风扇");
                fan_onOff(0);
            }
            else
            {
                ui->pushButton_fan->setText("关闭风扇");
                fan_onOff(1);
            }
        } else if (topic == TOPIC_H)
        {
            ui->label_H->setText(msg);
        }
        else if (topic == TOPIC_T) {
            ui->label_T->setText(msg);
        } else if (topic == TOPIC_S) {
            ui->label_S->setText(msg);
        } else if (topic == TOPIC_SUN) {
            ui->label_L->setText(msg);
        } else if (topic == TOPIC_W)
        {
            if(msg == "false")
            {
                ui->pushButton_window->setText("打开窗帘");
                set_step(0);
            }
            else
            {
                ui->pushButton_window->setText("关闭窗帘");
                set_step(1);
            }
        }
    }
}

void MainWindow::on_pushButton_window_clicked()
{
    if(ui->pushButton_window->text() == "打开窗帘")
    {
        ui->pushButton_window->setText("关闭窗帘");
        post(TOPIC_W, "true");
        set_step(1);
    }
    else
    {
        ui->pushButton_window->setText("打开窗帘");
        post(TOPIC_W, "false");
        set_step(0);
    }
}

void MainWindow::on_pushButton_led_clicked()
{
    if(ui->pushButton_led->text() == "开灯")
    {
        ui->pushButton_led->setText("关灯");
        //post(TOPIC_LED, "true");
        led_onOff(1);
    }
    else
    {
        ui->pushButton_led->setText("开灯");
        //post(TOPIC_LED, "false");
        led_onOff(0);
    }
}

void MainWindow::on_pushButton_fan_clicked()
{
    if(ui->pushButton_fan->text() == "打开风扇")
    {
        ui->pushButton_fan->setText("关闭风扇");
        fan_onOff(1);
        post(TOPIC_FAN, "true");

    }
    else
    {
        ui->pushButton_fan->setText("打开风扇");
        fan_onOff(0);
        post(TOPIC_FAN, "false");
    }
}

bool MainWindow::verifyChecksum(const QByteArray &data)
{
    quint8 sum = 0;
    for (int i = 0; i < 8; ++i) {
        sum += static_cast<quint8>(data[i]);
    }
    return sum == static_cast<quint8>(data[8]);
}

bool MainWindow::verifyChecksum(const QByteArray &data, quint8 crc)
{
    quint8 sum = 0;
    for (int i = 0; i < 14; ++i) {
        sum += static_cast<quint8>(data[i]);
    }
    //qDebug() << sum << crc;
    return sum == crc;
}
